VisualizeTimeFreq.m 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. function varargout = VisualizeTimeFreq(varargin)
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % Visualization HUB for timelock & frequency analysis data. %
  4. % Last modified: Feb.26, 2014 %
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. %
  7. % Usage:
  8. % VisualizeTimeFreq(BuilderMatFile)
  9. %
  10. % Inputs:
  11. % BuilderMatFile = Can be empty or specify target Builder .mat file
  12. % Copyright (C) 2013-2014, Michael J. Cheung
  13. %
  14. % This file is a part of the MEG & PLS Pipeline (MEGPLS). For more
  15. % details, see the documentation included with the software package.
  16. %
  17. % MEGPLS is free software: you can redistribute it and/or modify it under
  18. % the terms of the GNU General Public License version 2 as published by
  19. % the Free Software Foundation. This program is distributed in the hope
  20. % that it will be useful, but WITHOUT ANY WARRANTY; without even the
  21. % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  22. % See the GNU General Public License for more details.
  23. %
  24. % You should have received a copy of the GNU General Public License along
  25. % with this program. If not, you can download the license here:
  26. % <http://www.gnu.org/licenses/old-licenses/gpl-2.0>.
  27. % Last Modified by GUIDE v2.5 03-Mar-2014 15:16:15
  28. % Begin initialization code - DO NOT EDIT
  29. gui_Singleton = 1;
  30. gui_State = struct('gui_Name', mfilename, ...
  31. 'gui_Singleton', gui_Singleton, ...
  32. 'gui_OpeningFcn', @VisualizeTimeFreq_OpeningFcn, ...
  33. 'gui_OutputFcn', @VisualizeTimeFreq_OutputFcn, ...
  34. 'gui_LayoutFcn', [] , ...
  35. 'gui_Callback', []);
  36. if nargin && ischar(varargin{1})
  37. gui_State.gui_Callback = str2func(varargin{1});
  38. end
  39. if nargout
  40. [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
  41. else
  42. gui_mainfcn(gui_State, varargin{:});
  43. end
  44. % End initialization code - DO NOT EDIT
  45. %--- Executes just before VisualizeTimeFreq is made visible. ---%
  46. %-------------------------------------------------------%
  47. function VisualizeTimeFreq_OpeningFcn(hObject, eventdata, handles, varargin)
  48. % This function has no output args, see OutputFcn.
  49. % hObject handle to figure
  50. % eventdata reserved - to be defined in a future version of MATLAB
  51. % handles structure with handles and user data (see GUIDATA)
  52. % varargin command line arguments to VisualizeTimeFreq (see VARARGIN)
  53. % Choose default command line output for VisualizeTimeFreq
  54. handles.output = hObject;
  55. % Make sure toolbox paths are added:
  56. [PipelineDir, ~, ~] = fileparts(which('VisualizeTimeFreq.m'));
  57. addpath(genpath(PipelineDir));
  58. rmpath([PipelineDir,'/DEFAULT_SETTINGS']); % Make sure its calling from AnalysisID
  59. rmpath([PipelineDir,'/TEMPORARY_FIXES']); % Make sure its calling from FT toolbox
  60. CheckToolboxPaths(PipelineDir);
  61. % Initialize variables and default settings:
  62. handles.name.GroupID = [];
  63. handles.name.SubjID = [];
  64. handles.name.CondID = [];
  65. handles.paths = [];
  66. handles.gui.FreqMethod = []; % To check if mtmfft (plotted differently).
  67. handles.gui.SubjIDAvgList = []; % SubjID list with GrpAvg at end of list.
  68. handles.gui.ManualChannelSelect = [];
  69. handles.gui.PlotOverlap = 'no'; % For legend construction
  70. handles.gui.PlotGrpAvg = 'no';
  71. % Check for BuilderMat input:
  72. if isempty(varargin)
  73. handles.gui.BuilderMat = [];
  74. elseif numel(varargin) > 1
  75. disp('Error: Input should be empty or a Builder .mat file.')
  76. error('Incorrect number of inputs.')
  77. elseif exist(varargin{1}, 'file')
  78. handles.gui.BuilderMat = varargin{1};
  79. handles = LoadBuilderMat(handles, varargin{1});
  80. end
  81. % Update handles structure
  82. guidata(hObject, handles);
  83. % UIWAIT makes VisualizeTimeFreq wait for user response (see UIRESUME)
  84. % uiwait(handles.figure1);
  85. %--- Outputs from this function are returned to the command line. ---%
  86. %--------------------------------------------------------------------%
  87. function varargout = VisualizeTimeFreq_OutputFcn(hObject, eventdata, handles)
  88. % varargout cell array for returning output args (see VARARGOUT);
  89. % hObject handle to figure
  90. % eventdata reserved - to be defined in a future version of MATLAB
  91. % handles structure with handles and user data (see GUIDATA)
  92. % Get default command line output from handles structure
  93. varargout{1} = handles.output;
  94. %=====================================%
  95. % FUNCTIONS FOR LOADING BUILDER .MAT: %
  96. %=====================================%
  97. %--- Textbox to display selected path of Builder: ---%
  98. %----------------------------------------------------%
  99. function TextboxBuilderMat_Callback(hObject, eventdata, handles)
  100. EnteredText = get(handles.TextboxBuilderMat, 'String');
  101. if ~isequal(EnteredText, handles.gui.BuilderMat)
  102. set(handles.TextboxBuilderMat, 'String', handles.gui.BuilderMat);
  103. msgbox('Note: Use the button to change Builder .mat file.')
  104. end
  105. %--- Executes on button press in ButtonLoadBuilderMat. ---%
  106. %---------------------------------------------------------%
  107. function ButtonLoadBuilderMat_Callback(hObject, eventdata, handles)
  108. [BuilderFile, BuilderPath] = uigetfile('Builder_*.mat',...
  109. 'Select Builder .mat file to load:', 'MultiSelect', 'off');
  110. if BuilderFile == 0
  111. return; % If user cancels
  112. else
  113. handles.gui.BuilderMat = [BuilderPath,BuilderFile];
  114. set(handles.TextboxBuilderMat, 'String', handles.gui.BuilderMat);
  115. handles = LoadBuilderMat(handles, handles.gui.BuilderMat);
  116. guidata(hObject, handles);
  117. end
  118. %--- Loads variables from Builder .mat file. ---%
  119. %-----------------------------------------------%
  120. function OutputHandles = LoadBuilderMat(InputHandles, BuilderMat)
  121. handles = InputHandles;
  122. % Reset settings to default:
  123. handles.name.GroupID = [];
  124. handles.name.SubjID = [];
  125. handles.name.CondID = [];
  126. handles.paths = [];
  127. handles.gui.FreqMethod = []; % To check if mtmfft (plotted differently).
  128. handles.gui.SubjIDAvgList = []; % SubjID list with GrpAvg at end of list.
  129. handles.gui.ManualChannelSelect = [];
  130. handles.gui.PlotOverlap = 'no'; % For legend construction
  131. handles.gui.PlotGrpAvg = 'no';
  132. % Load Builder .mat:
  133. LoadBuilder = load(BuilderMat);
  134. handles.name = LoadBuilder.name;
  135. handles.paths = LoadBuilder.paths;
  136. handles.gui.FreqMethod = LoadBuilder.gui.FreqMethod;
  137. % Update GUI:
  138. GroupIndex = get(handles.ListboxGroupID, 'Value');
  139. set(handles.ListboxSubjID, 'Value', length(handles.name.SubjID{GroupIndex})+1);
  140. handles = UpdateNameIDs(handles);
  141. set(handles.TextboxBuilderMat, 'String', handles.gui.BuilderMat);
  142. % Set output handles:
  143. OutputHandles = handles;
  144. %============================%
  145. % FUNCTIONS FOR ID DISPLAYS: %
  146. %============================%
  147. %--- Executes on selection change in ListboxGroupID. ---%
  148. %-------------------------------------------------------%
  149. function ListboxGroupID_Callback(hObject, eventdata, handles)
  150. handles = UpdateNameIDs(handles);
  151. guidata(hObject, handles);
  152. %--- Executes on selection change in ListboxSubjID. ---%
  153. %------------------------------------------------------%
  154. function ListboxSubjID_Callback(hObject, eventdata, handles)
  155. handles = UpdateNameIDs(handles);
  156. guidata(hObject, handles);
  157. %--- Executes on selection change in ListboxCondID. ---%
  158. %------------------------------------------------------%
  159. function ListboxCondID_Callback(hObject, eventdata, handles)
  160. handles = UpdateNameIDs(handles);
  161. guidata(hObject, handles);
  162. %--- Update GroupID's, SubjID's, and CondID's: ---%
  163. %-------------------------------------------------%
  164. function OutputHandles = UpdateNameIDs(InputHandles)
  165. handles = InputHandles;
  166. % Update GroupID listbox:
  167. set(handles.ListboxGroupID, 'String', handles.name.GroupID);
  168. GroupIndex = get(handles.ListboxGroupID, 'Value');
  169. MaxGroupIndex = length(handles.name.GroupID);
  170. if isempty(GroupIndex) || GroupIndex == 0 || GroupIndex > MaxGroupIndex
  171. set(handles.ListboxGroupID, 'Value', MaxGroupIndex);
  172. end
  173. % Update SubjID listbox:
  174. if isempty(handles.name.SubjID)
  175. set(handles.ListboxSubjID, 'String', []);
  176. MaxSubjIndex = 0;
  177. else
  178. handles.gui.SubjIDAvgList{GroupIndex} = [handles.name.SubjID{GroupIndex}; 'GroupAvg'];
  179. set(handles.ListboxSubjID, 'String', handles.gui.SubjIDAvgList{GroupIndex});
  180. MaxSubjIndex = length(handles.gui.SubjIDAvgList{GroupIndex});
  181. end
  182. SubjIndices = get(handles.ListboxSubjID, 'Value');
  183. if isempty(SubjIndices) || max(SubjIndices) == 0 || max(SubjIndices) > MaxSubjIndex
  184. set(handles.ListboxSubjID, 'Value', MaxSubjIndex);
  185. end
  186. % Update CondID listbox:
  187. set(handles.ListboxCondID, 'String', handles.name.CondID);
  188. CondIndices = get(handles.ListboxCondID, 'Value');
  189. MaxCondIndex = length(handles.name.CondID);
  190. if isempty(CondIndices) || max(CondIndices) == 0 || max(CondIndices) > MaxCondIndex
  191. set(handles.ListboxCondID, 'Value', MaxCondIndex);
  192. end
  193. % Check SubjID & CondID multi-selection:
  194. % For frequency data (except for mtmfft), multiple datasets cannot be selected.
  195. if get(handles.ButtonViewFreqData, 'Value') == 1 && ...
  196. ~strcmp(handles.gui.FreqMethod, 'mtmfft')
  197. handles.gui.PlotOverlap = 'no';
  198. if length(SubjIndices) > 1
  199. set(handles.ListboxSubjID, 'Value', MaxSubjIndex);
  200. end
  201. if length(CondIndices) > 1
  202. set(handles.ListboxCondID, 'Value', 1);
  203. end
  204. else
  205. if length(SubjIndices) == 1 && length(CondIndices) == 1
  206. handles.gui.PlotOverlap = 'no';
  207. elseif length(SubjIndices) > 1 && length(CondIndices) == 1
  208. handles.gui.PlotOverlap = 'SubjIDs';
  209. elseif length(SubjIndices) == 1 && length(CondIndices) > 1
  210. handles.gui.PlotOverlap = 'CondIDs';
  211. elseif length(SubjIndices) > 1 && length(CondIndices) > 1
  212. handles.gui.PlotOverlap = 'Both';
  213. end
  214. end
  215. % Check if GroupAvg is selected:
  216. if isempty(handles.gui.SubjIDAvgList)
  217. handles.gui.PlotGrpAvg = 'no';
  218. else
  219. GroupIndex = get(handles.ListboxGroupID, 'Value');
  220. GrpAvgIndex = length(handles.gui.SubjIDAvgList{GroupIndex});
  221. if ismember(GrpAvgIndex, SubjIndices)
  222. handles.gui.PlotGrpAvg = 'yes';
  223. else
  224. handles.gui.PlotGrpAvg = 'no';
  225. end
  226. end
  227. % Set output handles:
  228. OutputHandles = handles;
  229. %======================================================%
  230. % FUNCTIONS FOR PLOTTING TIMELOCK / FREQUENCY RESULTS: %
  231. %======================================================%
  232. %--- Executes when selected object is changed in PanelPlotTimeFreq. ---%
  233. %----------------------------------------------------------------------%
  234. function PanelPlotTimeFreq_SelectionChangeFcn(hObject, eventdata, handles)
  235. % Enable multi-selection for timelock data:
  236. if get(handles.ButtonViewTimeData, 'Value') == 1
  237. set(handles.ListboxSubjID, 'Max', 2); % Enable multi-selection
  238. set(handles.ListboxCondID, 'Max', 2);
  239. set(handles.ButtonViewGFP, 'Enable', 'on'); % Enable GFP button.
  240. end
  241. % For frequency methods except for mtmfft, disable multi-selection:
  242. if get(handles.ButtonViewFreqData, 'Value') == 1
  243. if ~strcmp(handles.gui.FreqMethod, 'mtmfft')
  244. GroupIndex = get(handles.ListboxGroupID, 'Value');
  245. SubjIndices = get(handles.ListboxSubjID, 'Value');
  246. CondIndices = get(handles.ListboxCondID, 'Value');
  247. if length(SubjIndices) > 1
  248. set(handles.ListboxSubjID, 'Value', length(handles.gui.SubjIDAvgList{GroupIndex}));
  249. end
  250. if length(CondIndices) > 1
  251. set(handles.ListboxCondID, 'Value', 1);
  252. end
  253. set(handles.ListboxSubjID, 'Max', 1); % Disable multi-selection
  254. set(handles.ListboxCondID, 'Max', 1);
  255. end
  256. set(handles.ButtonViewGFP, 'Enable', 'off'); % Disable GFP button.
  257. end
  258. % Update handles:
  259. handles = UpdateNameIDs(handles);
  260. guidata(hObject, handles);
  261. %--- Executes on button press in ButtonViewTimeData.
  262. function ButtonViewTimeData_Callback(hObject, eventdata, handles)
  263. %--- Executes on button press in ButtonViewFreqData.
  264. function ButtonViewFreqData_Callback(hObject, eventdata, handles)
  265. %--- Executes on button press in ButtonPlotSettings. ---%
  266. %-------------------------------------------------------%
  267. function ButtonPlotSettings_Callback(hObject, eventdata, handles)
  268. if isempty(handles.gui.BuilderMat)
  269. msgbox('Warning: Select Builder .mat file first.', 'Warning:');
  270. return;
  271. end
  272. % Opens settings .m file:
  273. open([handles.paths.AnalysisID,'/SETTINGS/Settings_TimelockFreqPlot.m']);
  274. % --- Executes on button press in CheckboxInteractivePlots.
  275. function CheckboxInteractivePlots_Callback(hObject, eventdata, handles)
  276. %--- Acquires selected input time/freq data for plotting: ---%
  277. %------------------------------------------------------------%
  278. function [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetTimeFreqData(InputHandles)
  279. handles = InputHandles;
  280. paths = handles.paths;
  281. GroupIndex = get(handles.ListboxGroupID, 'Value');
  282. SubjIndices = get(handles.ListboxSubjID, 'Value');
  283. CondIndices = get(handles.ListboxCondID, 'Value');
  284. DataIndex = 1;
  285. MissingFiles = {};
  286. % Check to make sure multiselect is off for FreqAnalysis non-mtmfft data:
  287. if get(handles.ButtonViewFreqData, 'Value') == 1
  288. if ~strcmp(handles.gui.FreqMethod, 'mtmfft')
  289. if length(SubjIndices) > 1 || length(CondIndices) > 1
  290. TargetData = [];
  291. LegendData = [];
  292. LineStyles = [];
  293. ErrMsg = 'ERROR: Cannot select multiple datasets for TFR plot functions.';
  294. return;
  295. end
  296. end
  297. end
  298. % Load GrpAvg file(s) to be plotted first:
  299. if strcmp(handles.gui.PlotGrpAvg, 'yes')
  300. for c = CondIndices
  301. if get(handles.ButtonViewTimeData, 'Value') == 1
  302. TargetFile = paths.TimelockGrpAvg{GroupIndex}{c};
  303. elseif get(handles.ButtonViewFreqData, 'Value') == 1
  304. TargetFile = paths.FreqGrpAvg{GroupIndex}{c};
  305. end
  306. CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq');
  307. if CheckInput == 0
  308. MissingFiles = [MissingFiles; TargetFile];
  309. end
  310. TargetData{DataIndex} = TargetFile;
  311. LegendData{DataIndex} = ['GrpAvg_',handles.name.CondID{c}];
  312. if length(SubjIndices) == 1 % If only GRPAVG selected
  313. LineStyles{DataIndex} = '-';
  314. else
  315. LineStyles{DataIndex} = '.-';
  316. end
  317. DataIndex = DataIndex + 1;
  318. end
  319. end
  320. % Compile input datasets:
  321. for s = SubjIndices
  322. for c = CondIndices
  323. if s == length(handles.gui.SubjIDAvgList{GroupIndex})
  324. continue; % Skip GrpAvg index since already done above
  325. end
  326. if get(handles.ButtonViewTimeData, 'Value') == 1
  327. TargetFile = paths.Timelock{GroupIndex}{s,c};
  328. elseif get(handles.ButtonViewFreqData, 'Value') == 1
  329. TargetFile = paths.Freq{GroupIndex}{s,c};
  330. end
  331. CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq');
  332. if CheckInput == 0
  333. MissingFiles = [MissingFiles; TargetFile];
  334. end
  335. TargetData{DataIndex} = TargetFile;
  336. switch handles.gui.PlotOverlap
  337. case {'no', 'Both'}
  338. LegendData{DataIndex} = ...
  339. [handles.name.SubjID{GroupIndex}{s},'_',handles.name.CondID{c}];
  340. case 'SubjIDs'
  341. LegendData{DataIndex} = handles.name.SubjID{GroupIndex}{s};
  342. case 'CondIDs'
  343. LegendData{DataIndex} = handles.name.CondID{c};
  344. end
  345. if strcmp(handles.gui.PlotGrpAvg, 'yes')
  346. LineStyles{DataIndex} = '-'; % For now, keep non-grpavg lines solid
  347. else
  348. LineStyles{DataIndex} = '-';
  349. end
  350. DataIndex = DataIndex + 1;
  351. end % Cond
  352. end % Subj
  353. if ~isempty(MissingFiles)
  354. ErrMsg = {'ERROR: Selected file(s) could not be found.'};
  355. ErrMsg = [ErrMsg; MissingFiles];
  356. else
  357. ErrMsg = [];
  358. end
  359. %--- Executes on button press in ButtonViewMultiplot. ---%
  360. %--------------------------------------------------------%
  361. function ButtonViewMultiplot_Callback(hObject, eventdata, handles)
  362. if isempty(handles.gui.BuilderMat)
  363. msgbox('Warning: Select Builder .mat file first.', 'Warning:');
  364. return;
  365. end
  366. % Compile data to plot:
  367. [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetTimeFreqData(handles);
  368. if ~isempty(ErrMsg)
  369. msgbox(ErrMsg, 'Error:');
  370. return;
  371. end
  372. InputChannels = GetInputChannels(handles);
  373. % Get plot settings:
  374. CurrentDir = pwd;
  375. cd([handles.paths.AnalysisID,'/SETTINGS/']);
  376. [cfgPlotER, cfgPlotTFR] = Settings_TimelockFreqPlot(LineStyles);
  377. cd(CurrentDir);
  378. if get(handles.CheckboxInteractivePlots, 'Value') == 1
  379. cfgPlotER.interactive = 'yes';
  380. cfgPlotTFR.interactive = 'yes';
  381. else
  382. cfgPlotER.interactive = 'no';
  383. cfgPlotTFR.interactive = 'no';
  384. end
  385. % Plot data:
  386. figure;
  387. if get(handles.ButtonViewTimeData, 'Value') == 1
  388. cfgPlotER.legend = LegendData;
  389. cfgPlotER.channel = InputChannels;
  390. cfgPlotER.inputfile = TargetData;
  391. ft_multiplotER(cfgPlotER);
  392. elseif get(handles.ButtonViewFreqData, 'Value') == 1
  393. if strcmp(handles.gui.FreqMethod, 'mtmfft')
  394. cfgPlotER.legend = LegendData;
  395. cfgPlotER.channel = InputChannels;
  396. cfgPlotER.inputfile = TargetData;
  397. ft_multiplotER(cfgPlotER);
  398. else
  399. cfgPlotTFR.channel = InputChannels;
  400. cfgPlotTFR.inputfile = TargetData{1};
  401. ft_multiplotTFR(cfgPlotTFR);
  402. end
  403. end
  404. %--- Executes on button press in ButtonViewSingleplot. ---%
  405. %---------------------------------------------------------%
  406. function ButtonViewSingleplot_Callback(hObject, eventdata, handles)
  407. if isempty(handles.gui.BuilderMat)
  408. msgbox('Warning: Select Builder .mat file first.', 'Warning:');
  409. return;
  410. end
  411. % Compile data to plot:
  412. [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetTimeFreqData(handles);
  413. if ~isempty(ErrMsg)
  414. msgbox(ErrMsg, 'Error:');
  415. return;
  416. end
  417. InputChannels = GetInputChannels(handles);
  418. % Get plot settings:
  419. CurrentDir = pwd;
  420. cd([handles.paths.AnalysisID,'/SETTINGS/']);
  421. [cfgPlotER, cfgPlotTFR] = Settings_TimelockFreqPlot(LineStyles);
  422. cd(CurrentDir);
  423. if get(handles.CheckboxInteractivePlots, 'Value') == 1
  424. cfgPlotER.interactive = 'yes';
  425. cfgPlotTFR.interactive = 'yes';
  426. else
  427. cfgPlotER.interactive = 'no';
  428. cfgPlotTFR.interactive = 'no';
  429. end
  430. % Plot data:
  431. figure;
  432. if get(handles.ButtonViewTimeData, 'Value') == 1
  433. cfgPlotER.legend = LegendData;
  434. cfgPlotER.channel = InputChannels;
  435. cfgPlotER.inputfile = TargetData;
  436. ft_singleplotER(cfgPlotER);
  437. elseif get(handles.ButtonViewFreqData, 'Value') == 1
  438. if strcmp(handles.gui.FreqMethod, 'mtmfft')
  439. cfgPlotER.legend = LegendData;
  440. cfgPlotER.channel = InputChannels;
  441. cfgPlotER.inputfile = TargetData;
  442. ft_singleplotER(cfgPlotER);
  443. else
  444. % For ft_singleplotTFR, you need to load dataset (no cfg.inputfile option):
  445. InputData = [];
  446. InputData = LoadFTmat(TargetData{1}, 'ViewTimeFreq');
  447. cfgPlotTFR.channel = InputChannels;
  448. ft_singleplotTFR(cfgPlotTFR, InputData);
  449. end
  450. end
  451. %--- Acquires selected GFP data for plotting: ---%
  452. %------------------------------------------------%
  453. function [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetGFPData(InputHandles)
  454. handles = InputHandles;
  455. paths = handles.paths;
  456. GroupIndex = get(handles.ListboxGroupID, 'Value');
  457. SubjIndices = get(handles.ListboxSubjID, 'Value');
  458. CondIndices = get(handles.ListboxCondID, 'Value');
  459. DataIndex = 1;
  460. MissingFiles = {};
  461. % Check to make sure you are viewing timelock data::
  462. if get(handles.ButtonViewFreqData, 'Value') == 1
  463. TargetData = [];
  464. LegendData = [];
  465. LineStyles = [];
  466. ErrMsg = 'ERROR: Switch viewer to time-domain & ERP data to view GFP results.';
  467. return;
  468. end
  469. % Load GrpAvg file(s) to be plotted first:
  470. if strcmp(handles.gui.PlotGrpAvg, 'yes')
  471. for c = CondIndices
  472. TargetFile = paths.GlobalMeanFieldGrpAvg{GroupIndex}{c};
  473. CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq');
  474. if CheckInput == 0
  475. MissingFiles = [MissingFiles; TargetFile];
  476. end
  477. TargetData{DataIndex} = TargetFile;
  478. LegendData{DataIndex} = ['GrpAvg_',handles.name.CondID{c}];
  479. if length(SubjIndices) == 1 % If only GRPAVG selected
  480. LineStyles{DataIndex} = '-';
  481. else
  482. LineStyles{DataIndex} = '.-';
  483. end
  484. DataIndex = DataIndex + 1;
  485. end
  486. end
  487. % Compile input datasets:
  488. for s = SubjIndices
  489. for c = CondIndices
  490. if s == length(handles.gui.SubjIDAvgList{GroupIndex})
  491. continue; % Skip GrpAvg index since already done above
  492. end
  493. TargetFile = paths.GlobalMeanField{GroupIndex}{s,c};
  494. CheckInput = CheckPipelineMat(TargetFile, 'ViewTimeFreq');
  495. if CheckInput == 0
  496. MissingFiles = [MissingFiles; TargetFile];
  497. end
  498. TargetData{DataIndex} = TargetFile;
  499. switch handles.gui.PlotOverlap
  500. case {'no', 'Both'}
  501. LegendData{DataIndex} = ...
  502. [handles.name.SubjID{GroupIndex}{s},'_',handles.name.CondID{c}];
  503. case 'SubjIDs'
  504. LegendData{DataIndex} = handles.name.SubjID{GroupIndex}{s};
  505. case 'CondIDs'
  506. LegendData{DataIndex} = handles.name.CondID{c};
  507. end
  508. if strcmp(handles.gui.PlotGrpAvg, 'yes')
  509. LineStyles{DataIndex} = '-'; % For now, keep non-grpavg lines solid
  510. else
  511. LineStyles{DataIndex} = '-';
  512. end
  513. DataIndex = DataIndex + 1;
  514. end % Cond
  515. end % Subj
  516. if ~isempty(MissingFiles)
  517. ErrMsg = {'ERROR: Selected file(s) could not be found.'};
  518. ErrMsg = [ErrMsg; MissingFiles];
  519. else
  520. ErrMsg = [];
  521. end
  522. %--- Executes on button press in ButtonViewGFP. ---%
  523. %-------------------------------------------------------%
  524. function ButtonViewGFP_Callback(hObject, eventdata, handles)
  525. if isempty(handles.gui.BuilderMat)
  526. msgbox('Warning: Select Builder .mat file first.', 'Warning:');
  527. return;
  528. end
  529. % Compile GFP data to plot:
  530. [TargetData, LegendData, LineStyles, ErrMsg] = GetTargetGFPData(handles);
  531. if ~isempty(ErrMsg)
  532. msgbox(ErrMsg, 'Error:');
  533. return;
  534. end
  535. % Get plot settings:
  536. CurrentDir = pwd;
  537. cd([handles.paths.AnalysisID,'/SETTINGS/']);
  538. [cfgPlotER, ~] = Settings_TimelockFreqPlot(LineStyles);
  539. cd(CurrentDir);
  540. % Remove fields from cfgPlotER that don't apply:
  541. cfgPlotER = rmfield(cfgPlotER, 'channel');
  542. cfgPlotER = rmfield(cfgPlotER, 'baseline');
  543. cfgPlotER = rmfield(cfgPlotER, 'baselinetype');
  544. cfgPlotER = rmfield(cfgPlotER, 'layout');
  545. cfgPlotER = rmfield(cfgPlotER, 'maskstyle');
  546. % Plot data:
  547. figure;
  548. cfgPlotER.legend = LegendData;
  549. cfgPlotER.inputfile = TargetData;
  550. cfgPlotER.interactive = 'no'; % Force off, doesn't apply here.
  551. ft_singleplotER(cfgPlotER);
  552. %--- Executes on button press in ButtonCloseAll. ---%
  553. %---------------------------------------------------%
  554. function ButtonCloseAll_Callback(hObject, eventdata, handles)
  555. figs = get(0,'children');
  556. figs(figs == gcf) = []; % close all except GUI.
  557. close(figs)
  558. %==================================%
  559. % FUNCTIONS FOR CHANNEL SELECTION: %
  560. %==================================%
  561. %--- Executes when selected object is changed in PanelChannelSelect. ---%
  562. %-----------------------------------------------------------------------%
  563. function PanelChannelSelect_SelectionChangeFcn(hObject, eventdata, handles)
  564. handles = UpdateChannelSettings(handles);
  565. guidata(hObject, handles);
  566. % --- Executes on button press in ButtonAllChannels.
  567. function ButtonAllChannels_Callback(hObject, eventdata, handles)
  568. % --- Executes on button press in ButtonManualChannelSelect.
  569. function ButtonManualChannelSelect_Callback(hObject, eventdata, handles)
  570. %--- Compiles input channels for plotting: ---%
  571. %---------------------------------------------%
  572. function InputChannels = GetInputChannels(InputHandles)
  573. handles = InputHandles;
  574. if get(handles.ButtonAllChannels, 'Value') == 1
  575. InputChannels = 'MEG';
  576. return;
  577. end
  578. InputChannels = {};
  579. % Left channel groups:
  580. if get(handles.CheckboxMLF, 'Value') == 1
  581. InputChannels = [InputChannels; 'MLF'];
  582. end
  583. if get(handles.CheckboxMLC, 'Value') == 1
  584. InputChannels = [InputChannels; 'MLC'];
  585. end
  586. if get(handles.CheckboxMLO, 'Value') == 1
  587. InputChannels = [InputChannels; 'MLO'];
  588. end
  589. if get(handles.CheckboxMLP, 'Value') == 1
  590. InputChannels = [InputChannels; 'MLP'];
  591. end
  592. if get(handles.CheckboxMLT, 'Value') == 1
  593. InputChannels = [InputChannels; 'MLT'];
  594. end
  595. % Right channel groups:
  596. if get(handles.CheckboxMRF, 'Value') == 1
  597. InputChannels = [InputChannels; 'MRF'];
  598. end
  599. if get(handles.CheckboxMRC, 'Value') == 1
  600. InputChannels = [InputChannels; 'MRC'];
  601. end
  602. if get(handles.CheckboxMRO, 'Value') == 1
  603. InputChannels = [InputChannels; 'MRO'];
  604. end
  605. if get(handles.CheckboxMRP, 'Value') == 1
  606. InputChannels = [InputChannels; 'MRP'];
  607. end
  608. if get(handles.CheckboxMRT, 'Value') == 1
  609. InputChannels = [InputChannels; 'MRT'];
  610. end
  611. % Zenith channel groups:
  612. if get(handles.CheckboxMZF, 'Value') == 1
  613. InputChannels = [InputChannels; 'MZF'];
  614. end
  615. if get(handles.CheckboxMZC, 'Value') == 1
  616. InputChannels = [InputChannels; 'MZC'];
  617. end
  618. if get(handles.CheckboxMZO, 'Value') == 1
  619. InputChannels = [InputChannels; 'MZO'];
  620. end
  621. if get(handles.CheckboxMZP, 'Value') == 1
  622. InputChannels = [InputChannels; 'MZP'];
  623. end
  624. if get(handles.CheckboxMZT, 'Value') == 1
  625. InputChannels = [InputChannels; 'MZT'];
  626. end
  627. % Manually selected channels:
  628. if ~isempty(handles.gui.ManualChannelSelect)
  629. InputChannels = [InputChannels; handles.gui.ManualChannelSelect];
  630. end
  631. % --- Executes on button press in CheckboxMLF.
  632. function CheckboxMLF_Callback(hObject, eventdata, handles)
  633. % --- Executes on button press in CheckboxMLC.
  634. function CheckboxMLC_Callback(hObject, eventdata, handles)
  635. % --- Executes on button press in CheckboxMLO.
  636. function CheckboxMLO_Callback(hObject, eventdata, handles)
  637. % --- Executes on button press in CheckboxMLP.
  638. function CheckboxMLP_Callback(hObject, eventdata, handles)
  639. % --- Executes on button press in CheckboxMLT.
  640. function CheckboxMLT_Callback(hObject, eventdata, handles)
  641. % --- Executes on button press in CheckboxMRF.
  642. function CheckboxMRF_Callback(hObject, eventdata, handles)
  643. % --- Executes on button press in CheckboxMRC.
  644. function CheckboxMRC_Callback(hObject, eventdata, handles)
  645. % --- Executes on button press in CheckboxMRO.
  646. function CheckboxMRO_Callback(hObject, eventdata, handles)
  647. % --- Executes on button press in CheckboxMRP.
  648. function CheckboxMRP_Callback(hObject, eventdata, handles)
  649. % --- Executes on button press in CheckboxMRT.
  650. function CheckboxMRT_Callback(hObject, eventdata, handles)
  651. % --- Executes on button press in CheckboxMZF.
  652. function CheckboxMZF_Callback(hObject, eventdata, handles)
  653. % --- Executes on button press in CheckboxMZC.
  654. function CheckboxMZC_Callback(hObject, eventdata, handles)
  655. % --- Executes on button press in CheckboxMZO.
  656. function CheckboxMZO_Callback(hObject, eventdata, handles)
  657. % --- Executes on button press in CheckboxMZP.
  658. function CheckboxMZP_Callback(hObject, eventdata, handles)
  659. % --- Executes on button press in CheckboxMZT.
  660. function CheckboxMZT_Callback(hObject, eventdata, handles)
  661. % --- Executes on selection change in ListboxAddedChannels.
  662. function ListboxAddedChannels_Callback(hObject, eventdata, handles)
  663. %--- Executes on button press in ButtonManualAdd. ---%
  664. %----------------------------------------------------%
  665. function ButtonManualAdd_Callback(hObject, eventdata, handles)
  666. if isempty(handles.gui.BuilderMat)
  667. msgbox('Warning: Please select Builder .mat file first.', 'Warning:');
  668. return;
  669. end
  670. % Get channel data from first dataset:
  671. if exist(handles.paths.MEGdata{1}{1,1}, 'file')
  672. MEGdata = LoadFTmat(handles.paths.MEGdata{1}{1,1}, 'ViewTimeFreq');
  673. ChannelList = MEGdata.label;
  674. else
  675. msgbox('Error: Failed to acquire channel data (from first dataset).', 'Error:');
  676. return;
  677. end
  678. if ~isempty(handles.gui.ManualChannelSelect)
  679. ChannelList(find(ismember(ChannelList, handles.gui.ManualChannelSelect))) = [];
  680. end
  681. % Open listbox for channel selection:
  682. SelectedIndices = listdlg('PromptString', 'Manually select channels to view:', ...
  683. 'SelectionMode', 'multiple', 'ListString', ChannelList);
  684. if isempty(SelectedIndices)
  685. return; % If user cancels
  686. end
  687. SelectedChannels = ChannelList(SelectedIndices);
  688. handles.gui.ManualChannelSelect = [handles.gui.ManualChannelSelect; SelectedChannels];
  689. % Update handles:
  690. handles = UpdateChannelSettings(handles);
  691. guidata(hObject, handles);
  692. %--- Executes on button press in ButtonManualRemove. ---%
  693. %-------------------------------------------------------%
  694. function ButtonManualRemove_Callback(hObject, eventdata, handles)
  695. if isempty(handles.gui.BuilderMat)
  696. msgbox('Warning: Please select Builder .mat file first.', 'Warning:');
  697. return;
  698. end
  699. % Remove selected channels:
  700. SelectedIndices = get(handles.ListboxAddedChannels, 'Value');
  701. handles.gui.ManualChannelSelect(SelectedIndices) = [];
  702. % Update handles:
  703. handles = UpdateChannelSettings(handles);
  704. guidata(hObject, handles);
  705. %--- Updates channel selection settings: ---%
  706. %-------------------------------------------%
  707. function OutputHandles = UpdateChannelSettings(InputHandles)
  708. handles = InputHandles;
  709. % Update listboxes:
  710. set(handles.ListboxAddedChannels, 'String', handles.gui.ManualChannelSelect);
  711. SelectedIndices = get(handles.ListboxAddedChannels, 'Value');
  712. MaxIndex = length(handles.gui.ManualChannelSelect);
  713. if isempty(SelectedIndices) || max(SelectedIndices) == 0 || max(SelectedIndices) > MaxIndex
  714. set(handles.ListboxAddedChannels, 'Value', MaxIndex);
  715. end
  716. % Enable/Disable GUI components:
  717. if get(handles.ButtonAllChannels, 'Value') == 1
  718. set(findall(handles.PanelChannelGroups, '-property', 'Enable'), 'Enable', 'off');
  719. set(handles.ListboxAddedChannels, 'Enable', 'off');
  720. set(handles.ButtonManualAdd, 'Enable', 'off');
  721. set(handles.ButtonManualRemove, 'Enable', 'off');
  722. elseif get(handles.ButtonManualChannelSelect, 'Value') == 1
  723. set(findall(handles.PanelChannelGroups, '-property', 'Enable'), 'Enable', 'on');
  724. set(handles.ListboxAddedChannels, 'Enable', 'on');
  725. set(handles.ButtonManualAdd, 'Enable', 'on');
  726. set(handles.ButtonManualRemove, 'Enable', 'on');
  727. end
  728. % Set output handles:
  729. OutputHandles = handles;
  730. %==============================%
  731. % GUIDE "CREATEFCN" FUNCTIONS: %
  732. %==============================%
  733. % --- Executes during object creation, after setting all properties.
  734. function TextboxBuilderMat_CreateFcn(hObject, eventdata, handles)
  735. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  736. set(hObject,'BackgroundColor','white');
  737. end
  738. % --- Executes during object creation, after setting all properties.
  739. function ListboxGroupID_CreateFcn(hObject, eventdata, handles)
  740. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  741. set(hObject,'BackgroundColor','white');
  742. end
  743. % --- Executes during object creation, after setting all properties.
  744. function ListboxSubjID_CreateFcn(hObject, eventdata, handles)
  745. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  746. set(hObject,'BackgroundColor','white');
  747. end
  748. % --- Executes during object creation, after setting all properties.
  749. function ListboxCondID_CreateFcn(hObject, eventdata, handles)
  750. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  751. set(hObject,'BackgroundColor','white');
  752. end
  753. % --- Executes during object creation, after setting all properties.
  754. function ListboxAddedChannels_CreateFcn(hObject, eventdata, handles)
  755. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  756. set(hObject,'BackgroundColor','white');
  757. end